package com.lch.netty.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * nioserver端
 *
 * @author: liuchenhui
 * @create: 2019-07-21 14:53
 **/
public class NIOServerDemo {

    private Selector selector;

    private ByteBuffer buffer = ByteBuffer.allocate(102400);

    private int post;

    public NIOServerDemo(int post) {
        this.post = post;

        try {
            ServerSocketChannel server = ServerSocketChannel.open();

            server.bind(new InetSocketAddress(8080));

            // NIO 是BIO的升级版 为了兼容BIO, NIO模型默认是采用阻塞式
            server.configureBlocking(false);

            selector = Selector.open();

            server.register(selector, SelectionKey.OP_ACCEPT);

            System.out.println("listen on " + this.post + ".");

            while (true) {
                int select = selector.select();
                if (select <= 0) {
                    continue;
                }
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey next = iterator.next();
                    iterator.remove();

                    handleSelectionKey(next);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void handleSelectionKey(SelectionKey key) {
        try {
            if (key.isAcceptable()) {
                ServerSocketChannel server = (ServerSocketChannel) key.channel();
                SocketChannel channel = server.accept();
                channel.configureBlocking(false);
                channel.register(selector, SelectionKey.OP_READ);
                key.interestOps(SelectionKey.OP_ACCEPT);
            } else if (key.isReadable()) {
                SocketChannel channel = (SocketChannel) key.channel();
                StringBuffer stringBuffer = new StringBuffer();
                while (channel.read(buffer) > 0) {
                    buffer.flip();
                    stringBuffer.append(new String(buffer.array(), "UTF-8"));
                    buffer.clear();
                }
                String content = stringBuffer.toString();
                if (content.length() > 0) {
                    System.out.println("收到消息：" + content);
                    channel.register(selector, SelectionKey.OP_WRITE);
                    key.attach(content);
                }
            } else if (key.isWritable()) {
                SocketChannel channel = (SocketChannel) key.channel();
                String attachment = (String) key.attachment();
                if (attachment.length() >0 ){
                    channel.write(ByteBuffer.wrap(attachment.getBytes()));
                    channel.register(selector, SelectionKey.OP_READ);
                }
//                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        new NIOServerDemo(8080);
    }
}
